package com.cinema.servlet.booking;

import com.cinema.dao.*;
import com.cinema.entity.*;
import com.cinema.util.OrderUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 订票Servlet
 */
public class BookingServlet extends HttpServlet {
    private ShowtimeDAO showtimeDAO = new ShowtimeDAO();
    private SeatDAO seatDAO = new SeatDAO();
    private OrderDAO orderDAO = new OrderDAO();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String showtimeIdStr = request.getParameter("showtimeId");

        if (showtimeIdStr == null || showtimeIdStr.trim().isEmpty()) {
            response.sendRedirect(request.getContextPath() + "/movies");
            return;
        }

        try {
            Integer showtimeId = Integer.parseInt(showtimeIdStr);

            // 获取场次信息
            Showtime showtime = showtimeDAO.findById(showtimeId);
            if (showtime == null) {
                request.setAttribute("error", "场次不存在");
                request.getRequestDispatcher("/error/404.jsp").forward(request, response);
                return;
            }

            // 简化处理：直接获取座位信息，不检查canBook方法
            List<Seat> allSeats = new ArrayList<>();
            List<Integer> bookedSeatIds = new ArrayList<>();

            try {
                allSeats = seatDAO.findByHallId(showtime.getHallId());
                bookedSeatIds = seatDAO.getBookedSeatIds(showtimeId);
            } catch (Exception seatException) {
                // 如果获取座位信息失败，设置为空列表，让页面显示"暂无座位信息"
                System.out.println("获取座位信息失败: " + seatException.getMessage());
                seatException.printStackTrace();
            }

            request.setAttribute("showtime", showtime);
            request.setAttribute("allSeats", allSeats);
            request.setAttribute("bookedSeatIds", bookedSeatIds);
            request.getRequestDispatcher("/booking.jsp").forward(request, response);

        } catch (NumberFormatException e) {
            response.sendRedirect(request.getContextPath() + "/movies");
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取订票信息失败: " + e.getMessage());
            request.getRequestDispatcher("/error/500.jsp").forward(request, response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");

        String action = request.getParameter("action");

        if ("autoAssign".equals(action)) {
            handleAutoAssign(request, response, user);
        } else if ("manualSelect".equals(action)) {
            handleManualSelect(request, response, user);
        } else {
            response.sendRedirect(request.getContextPath() + "/movies");
        }
    }

    /**
     * 处理系统自动分配座位
     */
    private void handleAutoAssign(HttpServletRequest request, HttpServletResponse response, User user)
            throws ServletException, IOException {

        String showtimeIdStr = request.getParameter("showtimeId");
        String ticketCountStr = request.getParameter("ticketCount");

        try {
            Integer showtimeId = Integer.parseInt(showtimeIdStr);
            Integer ticketCount = Integer.parseInt(ticketCountStr);

            // 验证购票数量
            if (ticketCount <= 0 || ticketCount > 3) {
                request.setAttribute("error", "购票数量必须在1-3张之间");
                doGet(request, response);
                return;
            }

            // 获取场次信息
            Showtime showtime = showtimeDAO.findById(showtimeId);
            if (showtime == null || !showtimeDAO.canBookSimple(showtimeId)) {
                request.setAttribute("error", "该场次无法预订");
                doGet(request, response);
                return;
            }

            // 自动分配座位
            List<Seat> assignedSeats = seatDAO.autoAssignSeats(showtime.getHallId(), showtimeId, ticketCount);
            if (assignedSeats.size() < ticketCount) {
                request.setAttribute("error", "可用座位不足，请选择其他场次");
                doGet(request, response);
                return;
            }

            // 创建订单
            createOrder(request, response, user, showtime, assignedSeats);

        } catch (NumberFormatException e) {
            request.setAttribute("error", "参数错误");
            doGet(request, response);
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "订票失败，请稍后重试");
            doGet(request, response);
        }
    }

    /**
     * 处理手动选择座位
     */
    private void handleManualSelect(HttpServletRequest request, HttpServletResponse response, User user)
            throws ServletException, IOException {

        String showtimeIdStr = request.getParameter("showtimeId");
        String[] selectedSeatIds = request.getParameterValues("seatIds");

        try {
            Integer showtimeId = Integer.parseInt(showtimeIdStr);

            if (selectedSeatIds == null || selectedSeatIds.length == 0) {
                request.setAttribute("error", "请选择座位");
                doGet(request, response);
                return;
            }

            if (selectedSeatIds.length > 3) {
                request.setAttribute("error", "最多只能选择3个座位");
                doGet(request, response);
                return;
            }

            // 转换座位ID
            List<Integer> seatIds = new ArrayList<>();
            for (String seatIdStr : selectedSeatIds) {
                seatIds.add(Integer.parseInt(seatIdStr));
            }

            // 获取场次信息
            Showtime showtime = showtimeDAO.findById(showtimeId);
            if (showtime == null || !showtimeDAO.canBookSimple(showtimeId)) {
                request.setAttribute("error", "该场次无法预订");
                doGet(request, response);
                return;
            }

            // 检查座位是否可用
            if (!seatDAO.areSeatsAvailable(seatIds, showtimeId)) {
                request.setAttribute("error", "所选座位不可用，请重新选择");
                doGet(request, response);
                return;
            }

            // 获取座位信息
            List<Seat> selectedSeats = seatDAO.findByIds(seatIds);

            // 创建订单
            createOrder(request, response, user, showtime, selectedSeats);

        } catch (NumberFormatException e) {
            request.setAttribute("error", "参数错误");
            doGet(request, response);
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "订票失败，请稍后重试");
            doGet(request, response);
        }
    }

    /**
     * 创建订单
     */
    private void createOrder(HttpServletRequest request, HttpServletResponse response,
                           User user, Showtime showtime, List<Seat> seats)
            throws ServletException, IOException {

        try {
            // 计算总金额
            BigDecimal totalAmount = showtime.getPrice().multiply(BigDecimal.valueOf(seats.size()));

            // 生成订单号
            String orderNo = OrderUtil.generateOrderNo(user.getPhone());

            // 创建订单对象
            Order order = new Order();
            order.setOrderNo(orderNo);
            order.setUserId(user.getId());
            order.setShowtimeId(showtime.getId());
            order.setTotalAmount(totalAmount);
            order.setTicketCount(seats.size());
            order.setStatus("PENDING");
            order.setExpireTime(OrderUtil.calculateExpireTime(15)); // 15分钟过期

            // 获取座位ID列表
            List<Integer> seatIds = new ArrayList<>();
            for (Seat seat : seats) {
                seatIds.add(seat.getId());
            }

            // 创建订单（包含事务处理）
            Integer orderId = orderDAO.createOrder(order, seatIds);

            if (orderId != null) {
                // 减少可用座位数
                showtimeDAO.decreaseAvailableSeats(showtime.getId(), seats.size());

                // 跳转到支付页面
                response.sendRedirect(request.getContextPath() + "/user/payment?orderNo=" + orderNo);
            } else {
                request.setAttribute("error", "订单创建失败，请稍后重试");
                doGet(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "订票失败，请稍后重试");
            doGet(request, response);
        }
    }
}
